import {
  listInferencesWithPagination,
  countInferencesByFunction,
} from "~/utils/clickhouse/inference.server";
import type { Route } from "./+types/route";
import InferencesTable from "./InferencesTable";
import { data, isRouteErrorResponse, useNavigate } from "react-router";
import PageButtons from "~/components/utils/PageButtons";
import InferenceSearchBar from "./InferenceSearchBar";
import {
  PageHeader,
  PageLayout,
  SectionLayout,
} from "~/components/layout/PageLayout";
import { logger } from "~/utils/logger";

export async function loader({ request }: Route.LoaderArgs) {
  const url = new URL(request.url);
  const before = url.searchParams.get("before");
  const after = url.searchParams.get("after");
  const limit = Number(url.searchParams.get("limit")) || 10;
  if (limit > 100) {
    throw data("Limit cannot exceed 100", { status: 400 });
  }

  const [inferenceResult, countsInfo] = await Promise.all([
    listInferencesWithPagination({
      before: before || undefined,
      after: after || undefined,
      limit,
    }),
    countInferencesByFunction(),
  ]);

  const totalInferences = countsInfo.reduce((acc, curr) => acc + curr.count, 0);

  return {
    inferences: inferenceResult.inferences,
    hasNextPage: inferenceResult.hasNextPage,
    hasPreviousPage: inferenceResult.hasPreviousPage,
    limit,
    totalInferences,
  };
}

export default function InferencesPage({ loaderData }: Route.ComponentProps) {
  const { inferences, hasNextPage, hasPreviousPage, limit, totalInferences } =
    loaderData;

  const navigate = useNavigate();

  const topInference = inferences.at(0);
  const bottomInference = inferences.at(inferences.length - 1);

  const handleNextPage = () => {
    if (bottomInference) {
      navigate(`?before=${bottomInference.inference_id}&limit=${limit}`, {
        preventScrollReset: true,
      });
    }
  };

  const handlePreviousPage = () => {
    if (topInference) {
      navigate(`?after=${topInference.inference_id}&limit=${limit}`, {
        preventScrollReset: true,
      });
    }
  };

  return (
    <PageLayout>
      <PageHeader heading="Inferences" count={totalInferences} />
      <SectionLayout>
        <InferenceSearchBar />
        <InferencesTable inferences={inferences} />
        <PageButtons
          onPreviousPage={handlePreviousPage}
          onNextPage={handleNextPage}
          disablePrevious={!hasPreviousPage}
          disableNext={!hasNextPage}
        />
      </SectionLayout>
    </PageLayout>
  );
}

export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
  logger.error(error);

  if (isRouteErrorResponse(error)) {
    return (
      <div className="flex h-screen flex-col items-center justify-center gap-4 text-red-500">
        <h1 className="text-2xl font-bold">
          {error.status} {error.statusText}
        </h1>
        <p>{error.data}</p>
      </div>
    );
  } else if (error instanceof Error) {
    return (
      <div className="flex h-screen flex-col items-center justify-center gap-4 text-red-500">
        <h1 className="text-2xl font-bold">Error</h1>
        <p>{error.message}</p>
      </div>
    );
  } else {
    return (
      <div className="flex h-screen items-center justify-center text-red-500">
        <h1 className="text-2xl font-bold">Unknown Error</h1>
      </div>
    );
  }
}
